package com.dayuanit.dy15.ebook.bookshop.service.impl;

import com.dayuanit.dy15.ebook.bookshop.dto.NavigationDTO;
import com.dayuanit.dy15.ebook.bookshop.entity.Navigation;
import com.dayuanit.dy15.ebook.bookshop.mapper.NavigationMapper;
import com.dayuanit.dy15.ebook.bookshop.redis.RedisService;
import com.dayuanit.dy15.ebook.bookshop.service.NavigationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class NavigationServiceImpl implements NavigationService {

    @Autowired
    private NavigationMapper navigationMapper;

    @Resource(name = "redisServiceTempleImpl")
    private RedisService redisService;

    @Override
    public List<NavigationDTO> listAllNavigation() {
        // 先到缓存redis查询  没有则到数据库查询
        List<NavigationDTO> navigationDTOS = redisService.queryNav();
        //如果缓存中有，则表明命中缓存
        if (!navigationDTOS.isEmpty()) {
            System.out.println("导航栏命中缓存 yes");
            return navigationDTOS;
        }

        List<Navigation> navigations = navigationMapper.listAll();
        List<NavigationDTO> allDtos = new ArrayList<>(navigations.size());

        for (Navigation navigation : navigations) {
            NavigationDTO dto = new NavigationDTO();
            allDtos.add(dto);

            dto.setId(String.valueOf(navigation.getId()));
            dto.setLeaf(navigation.getLeaf());
            dto.setNavName(navigation.getNavName());
            dto.setParentNavId(String.valueOf(navigation.getParentNavId()));
            dto.setLevel(navigation.getLevel());
        }

        //第一级导航栏  最后将一级导航栏集合返回集合 因为经过递归之后，一级导航栏的childers集合就有了二级导航栏对象，
        //同理，二级导航栏对象的childer集合就有了三级导航对象。
        List<NavigationDTO> firstNavs = allDtos.stream()
                .filter(navigationDTO -> navigationDTO.getLevel() == 1)
                .collect(Collectors.toList());

        //调用递归 将二级和三级导航栏一次放进集合
        firstNavs.forEach(dto -> loopNav(dto, allDtos));

        //将数据放到redis缓存中
        redisService.cacheNav(firstNavs);
        System.out.println("导航栏缓存未命中，将数据缓存到redis中");
        return firstNavs;
    }

    private void loopNav(NavigationDTO currentNavDTO, List<NavigationDTO> allDtos) {
        //退出条件
        if (currentNavDTO.getLevel() == 3) {
            return;
        }

        //方案一：
//        List<NavigationDTO> childers = new ArrayList<>();
//        allDtos.forEach(dto -> {
//            if (dto.getParentNavId().equals(currentNavDTO.getId())) {
//                System.out.println(">>>" + dto.getNavName());
//                childers.add(dto);
//            }
//        });

        //方案二：从allDtos中过滤出当前currentNavDTO导航栏的直接子节点对象。放到集合中。
        List<NavigationDTO> childers = allDtos.stream().filter(dto -> dto.getParentNavId().equals(currentNavDTO.getId())).collect(Collectors.toList());
        //设置当前currentNavDTO导航栏的childer。
        currentNavDTO.setChilders(childers);

        //继续递归childer导航栏对象 直到木有只节点
        childers.forEach(child -> loopNav(child, allDtos));
    }
}
